package com.keya.aop.filter;


import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.keya.base.exception.BusinessException;
import com.keya.base.jwt.JwtProvider;
import com.keya.base.output.ResultData;
import com.keya.config.UrlMatcherConfig;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;


@WebFilter("/*")
@Component
@Slf4j
@Order(2)
public class LoginUserContextFilter implements Filter {

    @Resource
    JwtProvider jwtProvider;

    @Resource
    UrlMatcherConfig urlMatcherConfig;

    @SneakyThrows
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        httpRequest.setCharacterEncoding("utf-8");
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        httpServletResponse.setCharacterEncoding("utf-8");
        httpServletResponse.setContentType("text/html;charset=UTF-8");
        String requestURI = httpRequest.getRequestURI();
        try {
            boolean matches = urlMatcherConfig.matches(requestURI);
            if (matches) {
                chain.doFilter(httpRequest, httpServletResponse);
                return;
            }
            String urlToken = httpRequest.getParameter("token");
            if (StringUtils.isNotEmpty(urlToken)) {
                boolean b = jwtProvider.volatileFixationToken(urlToken);
                if (b) {
                    chain.doFilter(httpRequest, httpServletResponse);
                    return;
                }
                jwtProvider.validateToken(urlToken);
                chain.doFilter(httpRequest, httpServletResponse);
            } else {
                String token = httpRequest.getHeader("Authorization");
                if (StringUtils.isEmpty(token)) {
                    response1000(requestURI, httpServletResponse, 40004, "无token");
                } else {
                    boolean b = jwtProvider.volatileFixationToken(token);
                    if (b) {
                        chain.doFilter(httpRequest, httpServletResponse);
                        return;
                    }
                    b = jwtProvider.validateToken(token);
                    if (b) {
                        chain.doFilter(httpRequest, httpServletResponse);
                    }
                }
            }
        } catch (BusinessException e) {
            response1000(requestURI, httpServletResponse, e.getCode(), e.getMessage());
        } catch (Exception e) {
            log.error("过滤器异常", e);
            response1000(requestURI, httpServletResponse, 50000, "系统异常");
        }
    }


    @Override
    public void destroy() {

    }

    private void response1000(String requestURI, ServletResponse response, Integer code, String message) throws IOException {
        log.error("请注意！！！" + requestURI + "token无效");
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        httpServletResponse.setCharacterEncoding("utf-8");
        httpServletResponse.setStatus(401);
        ServletOutputStream outputStream = httpServletResponse.getOutputStream();
        ResultData resultData = ResultData.fail(code, message);
        outputStream.write(JSONObject.toJSONString(resultData, SerializerFeature.WriteMapNullValue).getBytes(StandardCharsets.UTF_8));
        outputStream.flush();
    }

}
